/*
 *  Copyright (C) 2010 Glauco
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.common.defaults;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.balisunrise.common.GridColumn;
import org.balisunrise.common.abstracts.AbstractBasic;

/**
 *
 * @author Glauco
 */
public class DefaultBaliColumn extends AbstractBasic implements GridColumn{

    /**
     * Métodos que são chamados para pegar as classes encapsuladas.
     */
    List<Method> calls;
    /**
     * Nome da Coluna.
     */
    String columnName;
    /**
     * Classe da Coluna
     */
    Class columnClass;
    /**
     * A Coluna é editavel no JTable.
     */
    boolean columnEditable;
    /**
     * Método get para a campo do objeto da coluna
     */
    Method getMethod;
    /**
     * Método set para o campo do objeto da coluna
     */
    Method setMethod;
    /**
     * Largura da coluna
     */
    int width;

    public DefaultBaliColumn(){
        calls = new ArrayList<Method>();
    }

    @Override
    public Object getValue(Object sourceObject){
        Object obj = doCalls(sourceObject);
        if (null == obj)
            return null;
        try{
            obj = getMethod.invoke(obj);
        }catch(Exception ex){
            throw new RuntimeException(ex.getCause());
        }
        return obj;
    }

    @Override
    public void setValue(Object value, Object sourceObject){
        Object obj = doCalls(sourceObject);
        if (null == obj)
            return;
        try{
            setMethod.invoke(obj, value);
        }catch(Exception e){
            throw new RuntimeException(e.getCause());
        }
    }

    private Object doCalls(Object sourceObject){
        if (null == sourceObject)
            throw new RuntimeException("Objeto da Lista de Busca é nulo!");
        Object obj = sourceObject;
        if(calls != null && calls.size() > 0){
            for (Method method : calls) {
                try{
                    obj = method.invoke(obj);
                    if (obj == null)
                        return null;
                }catch(Exception ex){
                    throw new RuntimeException(ex.getCause());
                }
            }
        }
        return obj;
    }

    @Override
    public Class getColumnClass() {
        return columnClass;
    }

    public void setColumnClass(Class columnClass) {
        this.columnClass = columnClass;
    }

    @Override
    public String getColumnName() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    @Override
    public boolean isColumnEditable() {
        return this.columnEditable;
    }

    public void setColumnEditable(boolean columnEditable) {
        this.columnEditable = columnEditable;
    }

    @Override
    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
    }

    public Method getGetMethod() {
        return getMethod;
    }

    public void setGetMethod(Method getMethod) {
        this.getMethod = getMethod;
    }

    @Override
    public Method[] getCalls() {
        return calls.toArray(new Method[]{});
    }

    @Override
    public void addCalls(Method method) {
        this.calls.add(method);
    }

    public Method getSetMethod() {
        return setMethod;
    }

    public void setSetMethod(Method setMethod) {
        this.setMethod = setMethod;
    }
}
